package cn.itcast.music.util;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.provider.MediaStore.Audio.Media;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import cn.itcast.music.R;
import cn.itcast.music.entity.Music;
import cn.itcast.music.entity.MusicHistory;
import cn.itcast.music.helper.HistoryHelper;
import cn.itcast.music.helper.MusicHelper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public abstract class MusicUtil {

    private static final String LOG_TAG = "App-MusicUtils";

    private static final String PACKAGE_PREFERENCES_NAME = "music";

    private static final String MUSIC_HISTORIES_PREFERENCE = "musicHistories";

    private MusicUtil() {
    }

    public static void initMusicData(Context context) {
        if (readonlyMusicList == null) {
            loadMusicList(context);
        }
        if (musicHistories == null) {
            loadMusicHistories(context);
        }
    }

    private static List<Music> readonlyMusicList;

    private static void loadMusicList(Context context) {
        long ignoreSeconds = 60;
        String[] ignoreFolders = new String[]{"/storage/emulated/0/Recordings",
                "/storage/emulated/0/Music/KugouRing"};

        Log.d(LOG_TAG, "正在扫描设备上的音乐");
        Log.d(LOG_TAG, "ignoreSeconds=" + ignoreSeconds);
        Log.d(LOG_TAG, "ignoreFolders=" + Arrays.toString(ignoreFolders));

        // 扫描本机音频
        ContentResolver resolver = context.getContentResolver();
        Uri uri = Media.EXTERNAL_CONTENT_URI;
        // 忽略短于指定时常、处于指定路径的音频
        StringBuilder selection = new StringBuilder(
                MediaColumns.DURATION + " > ?");
        List<String> selectionArgs = new ArrayList<>();
        selectionArgs.add(String.valueOf(ignoreSeconds * 1000));
        for (String ignorePath : ignoreFolders) {
            selection.append(" and ")
                    .append(MediaColumns.DATA)
                    .append(" not like ?");
            selectionArgs.add(ignorePath + "%");
        }
        Cursor cursor = resolver.query(uri, null, selection.toString(),
                selectionArgs.toArray(new String[0]), null);

        // 提取音频信息，整合为音乐列表
        MusicHelper musicHelper = new MusicHelper(context);
        readonlyMusicList = new ArrayList<>();
        if (cursor != null) {
            readonlyMusicList = extractMusicInfo(cursor, musicHelper);
            cursor.close();
        }

        // 转为只读列表
        readonlyMusicList = Arrays.asList(
                readonlyMusicList.toArray(new Music[0]));
    }

    @SuppressLint("Range")
    private static List<Music> extractMusicInfo(Cursor cursor,
            MusicHelper musicHelper) {
        List<Music> musicList = new ArrayList<>();
        while (cursor.moveToNext()) {
            long duration = cursor.getLong(
                    cursor.getColumnIndex(MediaColumns.DURATION));
            String path = cursor.getString(
                    cursor.getColumnIndex(MediaColumns.DATA));
            String title = cursor.getString(
                    cursor.getColumnIndex(MediaColumns.TITLE));
            String artist = cursor.getString(
                    cursor.getColumnIndex(MediaColumns.ARTIST));
            String album = cursor.getString(
                    cursor.getColumnIndex(MediaColumns.ALBUM));
            long size = cursor.getLong(
                    cursor.getColumnIndex(MediaColumns.SIZE));
            Music music = new Music(title, artist, album, path, duration, size);
            musicList.add(musicHelper.insert(music));
            Log.d(LOG_TAG, "提取到一条音乐信息：" + musicList.get(
                    musicList.size() - 1));
        }
        return musicList;
    }

    public static List<Music> getReadonlyMusicList() {
        return readonlyMusicList;
    }

    public static int positionInMusicList(Music music) {
        return readonlyMusicList.indexOf(music);
    }

    private static List<MusicHistory> musicHistories;

    private static void loadMusicHistories(Context context) {
        if (musicHistories == null) {
            HistoryHelper historyHelper = new HistoryHelper(context);
            musicHistories = historyHelper.selectAll();
            historyHelper.close();
            Log.d(LOG_TAG, "加载音乐历史记录：" + musicHistories);
        }
    }

    /**
     * 返回当前的历史记录（在历史记录变动之后，需要重新获取）
     *
     * @return 当前的历史记录
     */
    public static List<MusicHistory> getReadonlyMusicHistories() {
        // 返回只读 List
        return Arrays.asList(musicHistories.toArray(new MusicHistory[0]));
    }

    public static void addMusicHistory(Context context,
            MusicHistory musicHistory) {
        musicHistories.add(musicHistory);
        HistoryHelper historyHelper = new HistoryHelper(context);
        historyHelper.insert(musicHistory);
        historyHelper.close();
        Log.d(LOG_TAG, "添加音乐历史记录：" + musicHistory);
    }

    public static MusicHistory latestMusicHistory() {
        MusicHistory musicHistory = musicHistories.get(
                musicHistories.size() - 1);
        Log.d(LOG_TAG, "获取最近的音乐历史记录：" + musicHistory);
        return musicHistory;
    }

    public static void clearMusicHistories(Context context) {
        musicHistories.clear();
        HistoryHelper historyHelper = new HistoryHelper(context);
        historyHelper.deleteAll();
        historyHelper.close();
        Log.d(LOG_TAG, "清空音乐历史记录");
    }

    public static Bitmap getAlbumBitmap(Context context, String path) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        retriever.setDataSource(path);
        byte[] picture = retriever.getEmbeddedPicture();
        try {
            retriever.close();
        } catch (IOException e) {
            Log.e(LOG_TAG, "getAlbumBitmap: ", e);
        }
        if (picture != null) {
            return BitmapFactory.decodeByteArray(picture, 0, picture.length);
        } else {
            return BitmapFactory.decodeResource(context.getResources(),
                    R.mipmap.ic_launcher);
        }
    }

}
